﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using ImbaTracker.Models;
using ImbaTracker.Content;

namespace ImbaTracker.Controllers {
    [Authorize]
    public class IssueController : Controller {
        //
        // GET: /Issue/
        ImbaDBEntities db = new ImbaDBEntities();

        public ActionResult Index(bool onlyMy = false, Project project = null, bool closed = false) {
            IQueryable<Issue> issues;
            if (onlyMy) {
                issues = from i in db.Issues where i.Implementer.Login == User.Identity.Name select i;
            } else {
                issues = from i in db.Issues select i;
            }
            if (project != null && project.Id != 0) {
                 issues = from i in issues where i.Project.Id == project.Id select i;
            }
            int closedId = (from s in db.Status where s.Name == "Closed" select s.Id).Single();
            if (closed) {
                issues = from i in issues where i.Status.Id == closedId select i;
            } else {
                issues = from i in issues where i.Status.Id != closedId select i;
            }
            return View(issues.ToList());
        }

        public ActionResult MyIndex() {
            return RedirectToAction("Index", new { onlyMy = true });
        }

        public ActionResult Create(Project project) {
            var proj = db.Projects.FirstOrDefault(p1 => p1.Id == project.Id);
            InitializeReferences(null);
            var p = new List<Project>();
            p.Add(proj);
            this.ViewData["projects"] = new SelectList(p, "Id", "Name");
            this.ViewData["users"] = new SelectList(db.Users.ToList(), "Id", "Name");
            return View();
        }

        private void InitializeReferences(Issue curIssue) {
            this.ViewData["projects"] = new SelectList(db.Projects.ToList(), "Id", "Name");
            this.ViewData["users"] = new SelectList(db.Users.ToList(), "Id", "Name");
            this.ViewData["statuses"] = new SelectList(db.Status.ToList(), "Id", "Name");
            var issues = db.Issues.ToList();
            int deleted = issues.IndexOf(curIssue);
            if (deleted != -1) {
                issues.RemoveAt(deleted);
            }
            var newIssues = new List<Issue>();
            foreach (var member in issues)
                newIssues.Add
                    (new Issue() {
                        Id = member.Id,
                        Brief = member.Id + ". " + member.Brief
                    });
            this.ViewData["issues"] = new SelectList(new[] { new Issue() { Id = 0, Brief = "<Нет родителя>" } }.Concat(newIssues), "Id", "Brief");
        }

        [HttpPost]
        public ActionResult Create(Issue newIssue) {
            if (ModelState.IsValid) {
                var projectReference = db.Projects.Single(project => project.Id == newIssue.ProjectId);
                newIssue.Project = projectReference;
                var implementerReference = db.Users.Single(user => user.Id == newIssue.ImplementerId);
                newIssue.Implementer = implementerReference;
                var assignerReference = db.Users.Single(user => user.Login == User.Identity.Name);
                newIssue.Assigner = assignerReference;
                var parentReference = db.Issues.SingleOrDefault(issue => issue.Id == newIssue.ParentId);
                newIssue.Parent = parentReference;
                if (newIssue.Parent == null) {
                    newIssue.ParentId = null;
                }

                db.AddToIssues(newIssue);
                db.SaveChanges();

                return RedirectToAction("Index");
            } else {
                InitializeReferences(null);
                return View(newIssue);
            }
        }

        // GET: /Issue/Edit/

        public ActionResult Details(int id) {
            var issue = db.Issues.FirstOrDefault(i => i.Id == id);
            if (issue != null) {
                return View(issue);
            } else {
                return RedirectToAction("Index");
            }
        }

        public ActionResult Edit(int id = 0) {
            try {
                var issue = db.Issues.FirstOrDefault(ii => ii.Id == id);
                if (Helper.canProjectAccess(User)
                       || issue.Implementer.Login == User.Identity.Name
                       || issue.Assigner.Login == User.Identity.Name) {
                    InitializeReferences(issue);
                    return View(issue);
                } else {
                    return RedirectToAction("Index");
                }
            }
            catch (Exception e) {
                return RedirectToAction("Index");
            }
        }

        //
        // POST: /Issue/Edit/

        [HttpPost]
        public ActionResult Edit(Issue issue) {
            if (ModelState.IsValid) {
                // FUCK DAT SHIT, I'm going home, guys
                //try
                Issue target = db.Issues.Single(u => u.Id == issue.Id);

                target.Brief = issue.Brief;
                target.CriticalEndDate = issue.CriticalEndDate;
                target.Description = issue.Description;
                if (target.ImplementerId != issue.ImplementerId) {
                    var assignerReference = db.Users.Single(user => user.Login == User.Identity.Name);
                    target.Assigner = assignerReference;
                    target.AssignerId = assignerReference.Id;
                }
                target.Implementer = issue.Implementer;
                target.ImplementerId = issue.ImplementerId;
                target.Parent = issue.Parent;
                target.Status = issue.Status;
                target.ParentId = issue.ParentId == 0 ? null : issue.ParentId;
                target.PreferredEndDate = issue.PreferredEndDate;
                target.Priority = issue.Priority;
                target.StartDate = issue.StartDate;
                target.StatusId = issue.StatusId;

                //db.Issues.ApplyCurrentValues(target);
                db.SaveChanges();
                return RedirectToAction("Index");
                //catch (Exception e)
                //{
                //    return RedirectToAction("Error");
                //}
            }

            return View(issue);
        }
    }
}
